
package rendi456.swing.grid;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseListener;

import javax.swing.JPanel;

import rendi456.structure.grid.Grid;
import rendi456.structure.grid.GridAddress;
import rendi456.swing.PaneManager;

public class GridManager implements PaneManager
{
	public static final Color DEF_BACKGROUND_COLOR = Color.BLACK;
	public static final Color DEF_LINE_COLOR = Color.RED;
	public static final int DEF_LENGTH = 30;
	public static final int MIN_LENGTH = 2;

	private GridPane gridPane = null;
	private Grid grid = null;
	private Color lineColor = null;
	private int gridLength = 0;

	public GridManager(Grid<?> grid)
	{
		this(grid, GridManager.DEF_LENGTH);
	}

	public GridManager(Grid<?> grid, int gridLength)
	{
		this.grid = grid;

		this.gridPane = new GridPane();

		this.setLineColor(GridManager.DEF_LINE_COLOR);

		this.setGridLength(GridManager.DEF_LENGTH);
		this.updateSize();

		this.setGridLength(gridLength);
		this.updateSize();
	}

	@Override
	public void refresh()
	{
		if (this.gridPane != null)
		{
			this.gridPane.repaint();
		}
	}

	@Override
	public JPanel getPane()
	{
		return this.gridPane;
	}

	public void updateSize()
	{
		this.gridPane.setPreferredSize(this.getGridDimension());
	}

	@Override
	public String toString()
	{
		return this.grid.toString();
	}

	public static boolean validateGridLength(int length)
	{
		return length >= GridManager.MIN_LENGTH;
	}

	public void render(Graphics g)
	{
		this.paintGrid(g);
	}

	public int getGridHeight()
	{
		return this.grid.getRowCount() * this.gridLength;
	}

	public int getGridWidth()
	{
		return this.grid.getColumnCount() * this.gridLength;
	}

	public void paintGrid(Graphics g)
	{
		int temp = 0;
		int lengthDim = 0;
		int lineCount = 0;
		int length = GridManager.this.getGridLength();

		g.setColor(this.lineColor);

		// Drawing rows
		lengthDim = this.getGridWidth();
		lineCount = GridManager.this.grid.getRowCount();
		for (int i = 1; i < lineCount; i++)
		{
			temp = i * length;
			g.drawLine(0, temp, lengthDim, temp);
		}

		// Drawing columns`
		lengthDim = this.getGridHeight();
		lineCount = GridManager.this.grid.getColumnCount();
		for (int i = 1; i < lineCount; i++)
		{
			temp = i * length;
			g.drawLine(temp, 0, temp, lengthDim);
		}
	}

	public Dimension getGridDimension()
	{
		return new Dimension(this.getGridWidth(), this.getGridHeight());
	}

	public Color getLineColor()
	{
		return this.lineColor;
	}

	private boolean setGridLength(int length)
	{
		boolean ok = GridManager.validateGridLength(length);
		if (ok)
		{
			this.gridLength = length;
		}
		return ok;
	}

	public int getGridLength()
	{
		return this.gridLength;
	}

	public boolean setLineColor(Color lineColor)
	{
		boolean ok = true;
		if (ok)
		{
			this.lineColor = lineColor;
		}
		return ok;
	}

	public GridAddress getGridAddress(Point p)
	{
		return this.getGridAddress(p.x, p.y);
	}

	public GridAddress getGridAddress(int x, int y)
	{
		return new GridAddress(y / this.gridLength, x / this.gridLength);
	}

	public Grid<?> getGrid()
	{
		return this.grid;
	}

	private class GridPane extends JPanel
	{
		public GridPane()
		{
			this.setBackground(GridManager.DEF_BACKGROUND_COLOR);
		}

		@Override
		public void paintComponent(Graphics g)
		{
			super.paintComponent(g);

			if (GridManager.this.grid != null)
			{
				GridManager.this.render(g);
			}
		}
	}
}
